package com.mjk.manager.gen.impl.interfaces;

import com.mjk.common.tools.gson.GsonUtils;
import com.mjk.common.tools.logger.BizLogger;
import com.mjk.common.util.ObjectUtils;
import com.mjk.common.util.StrUtils;
import com.mjk.manager.api.dto.ApiFieldEntity;
import com.mjk.manager.api.model.ApiModel;
import com.mjk.manager.gen.dto.GenDto;
import groovy.lang.GroovyClassLoader;
import org.springframework.util.CollectionUtils;

import java.util.List;

public class HttpGenImpl implements InterfacesGen {
	/**
	 * 生成类的常量
	 */
	public static final String API_CLASS = """
	   package com.mjk.manager.api.work;
	   import com.mjk.common.core.jdbc.service.parse.type.BeeParseType;
	   import java.util.List;
	   import org.springframework.util.CollectionUtils;
	   import com.mjk.common.core.jdbc.service.plus.idbservice.BeeDBService;
	   import com.mjk.common.util.ObjectUtils;
	   import java.util.HashMap;
	   import java.util.Map;
	   import com.mjk.common.util.BeanUtils;
	   import org.apache.commons.collections.MapUtils;
	   import org.springframework.beans.factory.annotation.Autowired;
	   import com.mjk.common.base.response.BeeResponse;
	   import com.mjk.common.base.work.BaseWork;
	   import com.mjk.common.base.work.annotation.BeeWork;
	   import com.mjk.common.base.error.BeeError;
	   import com.mjk.manager.api.dto.ApiDto;
	   import com.mjk.manager.api.mapper.ApiMapper;
	   import com.mjk.common.tools.gson.GsonUtils;
	   import com.mjk.common.tools.logger.BizLogger;
	   import com.mjk.manager.api.model.ApiModel;
	   @BeeWork(work="%s",isDynamic=true)
	   public class %s extends BaseWork{
		   @Autowired
		   private ApiMapper mapper;
		   @Autowired
		   private BeeDBService beeDBService;
			 %s 
		};
	""";
	/**
	 * 生产普通获取方法的常量
	 */
	private static final String API_METHOD_SELECT = """
		public BeeResponse %s(ApiDto dto){
		   %s
		   Map<String,Object> params = BeanUtils.beanToMap(dto);
		   String str ="%s";
		   Map<String,Object> sqlResult=BeeParseType.getParsing(BeeParseType.SQL).parsing(str, params);
		   return BeeError.BEE_SUC.tranceError(sqlResult);
		}   
		""";
	/**
	 * 生成复杂方法 通过存储过程
	 */
	private static final String API_METHOD_PROCEDURE = """
			public BeeResponse %s(ApiDto dto){
				%s
				Map<String,Object> map = new HashMap<String,Object>();
				map.put("procedure", %s);
				String params = "%s";
				if(params.contains(",")){
				  for(String s : params.split(",")){
					 map.put(s, getVaule(dto,s));
				  }
				}else{
				  map.put(params, getVaule(dto,params));
				}
				mapper.executeProcedure(map);
				String result = MapUtils.getString(map, "outCode");
				if("0".equals(result)){
				  return BeeError.BEE_SUC.tranceError(MapUtils.getInteger(map, "data"));
				}else{
				  return BeeError.BEE_FAILD.tranceError(MapUtils.getInteger(map, "outMsg"));
				}
			};
			""";

	
	private static final String PARAMS_NEED = " needParams(dto, %s); \r\n";
	
	@SuppressWarnings("resource")
	public Class<?> createClass(GenDto dto){
		if(ObjectUtils.isEmpty(dto.getModel().getApiWork())){
			return null;
		}
		String className = StrUtils.toUpperCaseFirstOne(dto.getModel().getApiWork())+"WorkProxy";
        //groovy提供了一种将字符串文本代码直接转换成Java Class对象的功能
		try(GroovyClassLoader groovyClassLoader = new GroovyClassLoader()){
			String classStr = String.format(API_CLASS, dto.getModel().getApiWork(),className,createMethods(dto.getModels()));
	        //System.out.println(classStr);
	        //里面的文本是Java代码,但是我们可以看到这是一个字符串我们可以直接生成对应的Class<?>对象,而不需要我们写一个.java文件
	        return groovyClassLoader.parseClass(classStr);
		}catch(Exception e) {
			//do noting
			BizLogger.error(e);
		}
        return null;
	}
	/**
	 * 创建方法
	 * @param models
	 * @return
	 */
	public String createMethods(List<ApiModel> models){
		if(CollectionUtils.isEmpty(models)){
			return "";
		}
		StringBuilder sb = new StringBuilder();
		for(ApiModel model : models){
			if("1".equals(model.getType())){
				model.setSelectSql(model.getSelectSql().replaceAll("[\r\n]+", ""));
				model.setSelectSql(model.getSelectSql().replace("\"", "\\\""));
				sb.append(String.format(API_METHOD_SELECT, model.getApiMethod(),getNeedParams(model),model.getSelectSql()));
			}else if("2".equals(model.getType())){
				sb.append(String.format(API_METHOD_PROCEDURE, model.getApiMethod(),getNeedParams(model),model.getProcedureName(),getNeedStr(model)));
			}
		}
		return sb.toString();
	}
	
	public String getNeedParams(ApiModel model){
		String needStr = getNeedStr(model);
		if(ObjectUtils.isEmpty(needStr)){
			return "";
		}
		
		return String.format(PARAMS_NEED, getNeedStr(model));
	}
	
	@SuppressWarnings("unchecked")
	public String getNeedStr(ApiModel model){
		String result = "";
		if(null==model || ObjectUtils.isEmpty(model.getParams())){
		  return result;
		}
		List<ApiFieldEntity> entitys =  GsonUtils.json2List(model.getParams(), ApiFieldEntity.class);
		StringBuilder sb = new StringBuilder();
		for(ApiFieldEntity entity : entitys){
			if(!ObjectUtils.isEmpty(entity.getField())){
				sb.append("\""+entity.getField()+"\",");
			}
		}
		if(sb.toString().endsWith(",")){
			result = sb.substring(0, sb.toString().length()-1);
		}		
		return result;
	}
}
